﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace FasterWPF
{
    public static class MenuItemExt
    {
        #region SubMenuItem ControlTemplate

            //     <ControlTemplate x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type MenuItem}, ResourceId=SubmenuItemTemplateKey}"
            //                 TargetType="{x:Type MenuItem}">
            //    <Grid SnapsToDevicePixels="true">
            //        <Rectangle Name="Bg"
            //                   Fill="{TemplateBinding MenuItem.Background}"
            //                   Stroke="{TemplateBinding MenuItem.BorderBrush}"
            //                   StrokeThickness="1"
            //                   RadiusX="2"
            //                   RadiusY="2"/>
            //        <Rectangle x:Name="InnerBorder"
            //                   Margin="1"
            //                   RadiusX="2"
            //                   RadiusY="2"/>
            //        <Grid>
            //            <Grid.ColumnDefinitions>
            //                <ColumnDefinition MinWidth="24"
            //                                  Width="Auto"
            //                                  SharedSizeGroup="MenuItemIconColumnGroup"/>
            //                <ColumnDefinition Width="4"/>
            //                <ColumnDefinition Width="*"/>
            //                <ColumnDefinition Width="37"/>
            //                <ColumnDefinition Width="Auto"
            //                                  SharedSizeGroup="MenuItemIGTColumnGroup"/>
            //                <ColumnDefinition Width="17"/>
            //            </Grid.ColumnDefinitions>
            //            <ContentPresenter x:Name="Icon"
            //                              Margin="1"
            //                              VerticalAlignment="Center"
            //                              ContentSource="Icon"
            //                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            //            <Border x:Name="GlyphPanel"
            //                    Background="#E6EFF4"
            //                    BorderBrush="#CDD3E6"
            //                    BorderThickness="1"
            //                    CornerRadius="3"
            //                    Margin="1"
            //                    Visibility="Hidden"
            //                    Width="22" 
            //                    Height="22">
            //                <Path Name="Glyph"
            //                      Width="9"
            //                      Height="11"
            //                      Fill="#0C12A1"
            //                      FlowDirection="LeftToRight"
            //                      Data="{StaticResource Checkmark}"/>
            //            </Border>
            //            <ContentPresenter Grid.Column="2"
            //                              ContentSource="Header"
            //                              Margin="{TemplateBinding MenuItem.Padding}"
            //                              RecognizesAccessKey="True"
            //                              SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
            //            <TextBlock Grid.Column="4"
            //                       Text="{TemplateBinding MenuItem.InputGestureText}"
            //                       Margin="{TemplateBinding MenuItem.Padding}"/>
            //        </Grid>
            //    </Grid>
            //    <ControlTemplate.Triggers>
            //        <Trigger Property="Icon"
            //                 Value="{x:Null}">
            //            <Setter TargetName="Icon"
            //                    Property="Visibility"
            //                    Value="Collapsed"/>
            //        </Trigger>
            //        <Trigger Property="IsChecked"
            //                 Value="true">
            //            <Setter TargetName="GlyphPanel"
            //                    Property="Visibility"
            //                    Value="Visible"/>
            //            <Setter TargetName="Icon"
            //                    Property="Visibility"
            //                    Value="Collapsed"/>
            //        </Trigger>
            //        <Trigger Property="IsHighlighted"
            //                 Value="true">
            //            <Setter TargetName="Bg"
            //                    Property="Fill"
            //                    Value="{StaticResource MenuItemSelectionFill}"/>
            //            <Setter TargetName="Bg"
            //                    Property="Stroke"
            //                    Value="#8071CBF1"/>
            //            <Setter TargetName="InnerBorder"
            //                    Property="Stroke"
            //                    Value="#40FFFFFF"/>
            //        </Trigger>
            //        <Trigger Property="IsEnabled"
            //                 Value="false">
            //            <Setter Property="Foreground"
            //                    Value="#FF9A9A9A"/>
            //            <Setter TargetName="GlyphPanel"
            //                    Property="Background"
            //                    Value="#EEE9E9"/>
            //            <Setter TargetName="GlyphPanel"
            //                    Property="BorderBrush"
            //                    Value="#DBD6D6"/>
            //            <Setter TargetName="Glyph"
            //                    Property="Fill"
            //                    Value="#848589"/>
            //        </Trigger>
            //    </ControlTemplate.Triggers>
            //</ControlTemplate>
        #endregion

        public static void SetMenuOrientationToVertical(Menu subMenu1)
        {
            var vstpFactory = new FrameworkElementFactory(typeof(VirtualizingStackPanel));
            vstpFactory.SetValue(VirtualizingStackPanel.OrientationProperty, Orientation.Vertical);
            subMenu1.ItemsPanel = new ItemsPanelTemplate(vstpFactory);
        }

        public static void HideSubMenu(Canvas cnvsA, string canvasguid)
        {
            if (cnvsA.IsCompositeOnParent<Canvas>(canvasguid))
            {
                cnvsA.RemoveByKey<Canvas>(canvasguid);
            }
        }

        public static void DisplaySubMenu(Canvas cnvsA, string canvasguid, Border subMenu, double? left, double? top, int? zIndex)
        {
            if (!cnvsA.IsCompositeOnParent<Canvas>(canvasguid))
            {
                cnvsA.BeginComposite(canvasguid)
                .AddExisting<Border, Canvas>(0, 0, subMenu)
                .EndComposite<Canvas, CanvasArgs>(new CanvasArgs(left, top, zIndex));
            }
        }

        public static void ChangeForegroundColorOnMenuItem(MenuItem mnuItem, Brush newColor, FontSettings fs, Brush outerBorderColor)
        {
            if (mnuItem != null)
            {
                //set via style since we will be varying via OnMouseOver
                Style style = new Style(typeof(MenuItem), mnuItem.Style);

                Setter setter = new Setter();
                setter.Property = MenuItem.ForegroundProperty;
                setter.Value = newColor;
                style.Setters.Add(setter);
                Setter setter2 = new Setter();
                setter2.Property = MenuItem.BorderBrushProperty;
                setter2.Value = outerBorderColor;
                style.Setters.Add(setter2);
                mnuItem.Style = style;
     
                //set these directly since we won't be varying via OnMouseOver
                mnuItem.FontFamily = new FontFamily(fs.FontFamily);
                mnuItem.FontSize = fs.FontSize;
                mnuItem.FontStyle = fs.FontStyle;
                mnuItem.FontWeight = fs.FontWeight;
            }
        }

        public static MenuItem SetMouseOverForegroundOnMenuItem(this MenuItem mnuItem, Brush brush)
        {
            Style style = new Style(typeof(MenuItem), mnuItem.Style);
            Trigger t = new Trigger();
            t.Property = MenuItem.IsMouseOverProperty;
            t.Value = true;

            Setter setter = new Setter();
            setter.Property = MenuItem.ForegroundProperty;
            setter.Value = brush;
            t.Setters.Add(setter);

            style.Triggers.Add(t); // Important: add a trigger before applying style
            mnuItem.Style = style;

            return mnuItem;
        }

        public static void ChangeBackgroundColorOnMenuItem(this MenuItem button, Brush newColor)
        {
            if (button != null)
            {
                var builtCheck = button.ApplyTemplate();
                Rectangle bd = (Rectangle)button.Template.FindName("Bg", button);
                
                bd.Fill = newColor;
            }
        }

        public static void SetMenuItemGlyphPanelMarginToZero(this MenuItem parentBorder)
        {
            var builtCheck = parentBorder.ApplyTemplate();
            object gp = parentBorder.Template.FindName("GlyphPanel", parentBorder);
            (gp as Border).Margin = new Thickness(0);
           
            //change from 2,3,2,3
            parentBorder.Padding = new Thickness(0, 3, 0, 3);

            //change <ColumnDefinition Width="37"/> to Width = "3"
            object iconPresenter = parentBorder.Template.FindName("Icon", parentBorder);
            Grid innerGrid = ((iconPresenter as ContentPresenter).Parent as Grid);
            innerGrid.ColumnDefinitions[3].Width = new GridLength(3);
        }

        public static MenuItem SetMouseOverColorOnMenuItem(this MenuItem parentBorder, double mouseOverRectangleWidth, double mouseOverRectangleHeight, Brush brush, Brush innerBorderColor, Brush outerBorderColor)
        {
           var builtCheck = parentBorder.ApplyTemplate();
           Rectangle bd1 = (Rectangle)parentBorder.Template.FindName("Bg", parentBorder);
           object io= parentBorder.Template.FindName("InnerBorder", parentBorder);            
           Brush currentInnerBrush = io.Cast<Rectangle>().Stroke;      
            
           bd1.Width = mouseOverRectangleWidth;
           (io as Rectangle).Width = mouseOverRectangleWidth;
           bd1.Height = mouseOverRectangleHeight;
           (io as Rectangle).Height = mouseOverRectangleHeight;
           bd1.HorizontalAlignment = HorizontalAlignment.Left;
           (io as Rectangle).HorizontalAlignment = HorizontalAlignment.Left;

           Brush currentBrush = bd1.Fill;
           Brush currentBorder = bd1.Stroke;

           parentBorder.SubscribeEventOnParent<MenuItem, MouseEventArgs>("MouseEnter",
                ((o,e) => {
                    bd1.Fill = brush;
                    if (innerBorderColor != null)
                    {
                        bd1.Stroke = outerBorderColor;
                        io.Cast<Rectangle>().Stroke = innerBorderColor;
                    }
                }));

           parentBorder.SubscribeEventOnParent<MenuItem, MouseEventArgs>("MouseLeave",
                ((o, e) =>
                { 
                    
                bd1.Fill = currentBrush;
                io.Cast<Rectangle>().Stroke = currentInnerBrush;
                bd1.Stroke = currentBorder;
                FrameworkElement primaryGrid = (FrameworkElement)parentBorder.GetParentFromChildElement<Menu>().Parent;
                    primaryGrid.Focusable=true;
                    primaryGrid.Focus();
                }));
 
            return parentBorder;

            //Consider adding support for disabled vs. enabled icon?

            //DataTrigger trg = new DataTrigger();
            //Binding trgBinding = new Binding();
            //trgBinding.ElementName = "img";
            //trgBinding.Path = new PropertyPath("IsEnabled");
            //trg.Value = false;
            //trg.Binding = trgBinding;
            //imgStyle.Triggers.Add(trg);

            //imgSetter = new Setter();
            //imgSetter.Property = Image.SourceProperty;
            //imgSetter.Value = disabledImage;
            //trg.Setters.Add(imgSetter);
            //menuIcon.SetValue(Image.StyleProperty, imgStyle);
        }

        public static MenuItem Initialize(this MenuItem source, double width, double height, ContainerType containerType, Brush background, Brush foreground, FontSettings fs, Brush outerBorderColor)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            ChangeForegroundColorOnMenuItem(source, foreground, fs, outerBorderColor);

            ChangeBackgroundColorOnMenuItem(source, background);

            sharedMenuItemInitializeCode(source, width, height, containerType);
          
            return source;
        }

        public static MenuItem Initialize(this MenuItem source, double width, double height, ContainerType containerType, Brush foreground, FontSettings fs, Brush outerBorderColor)
        {   
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            ChangeForegroundColorOnMenuItem(source, foreground, fs, outerBorderColor);

            sharedMenuItemInitializeCode(source, width, height, containerType);

            return source;
        }

        public static MenuItem Initialize(this MenuItem source, double width, double height, ContainerType containerType)
        {
            //Force the Aero theme by default to assure the structure of the Listbox
            Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
            source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);

            sharedMenuItemInitializeCode(source, width, height, containerType);

            return source;
        }


        private static void sharedMenuItemInitializeCode(MenuItem source, double width, double height, ContainerType containerType)
        {
            source.HorizontalAlignment = HorizontalAlignment.Left;
            source.VerticalAlignment = VerticalAlignment.Top;

            source.Width = width;
            source.Height = height;
            source.SetContainerType(containerType);
            IComposite icomp = CompositeTypeHelper.CreateIComposite<MenuItem>(source);
            source.SetIComposite<MenuItem>(icomp);

            //STORE SETTING BUILD CHAIN AND GET CHAIN?!?  Put these in a Composite implements an interface
            MenuItemParent gbsr = new MenuItemParent();
            source.StoreSetting<MenuItem>("IParent", gbsr);

            source.StoreSetting<MenuItem>("ObsCol", new ObservableCollection<MenuItem>());

            source.AddItemBorder(Brushes.Gray, new Thickness(1, 1, 1, 1)); //default Border     
            source.StoreSetting<MenuItem>("BorderSettings", new BorderSettings() { Width = double.NaN, Height = double.NaN, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(0, 0, 0, 0), CornerRadius = new CornerRadius(0), Padding = new Thickness(0) });
        }
        
    }//end of class
}//end of namespace
